package cn.itcalvin.sncoal.cth.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.itcalvin.sncoal.cth.component.ConfigCacheUtils;
import cn.itcalvin.sncoal.cth.domain.ConfigSystem;
import cn.itcalvin.sncoal.cth.domain.ConfigSystemZb;
import cn.itcalvin.sncoal.cth.mapper.main.InfoPfSystemMapper;
import cn.itcalvin.sncoal.cth.pojo.common.ReqLong;
import cn.itcalvin.sncoal.cth.pojo.common.RespSelect;
import cn.itcalvin.sncoal.cth.pojo.common.RespUserInfo;
import cn.itcalvin.sncoal.cth.pojo.req.analyse.ReqAnalyseGetZbDetails;
import cn.itcalvin.sncoal.cth.pojo.response.analyse.*;
import cn.itcalvin.sncoal.cth.service.AnalyseService;
import cn.itcalvin.sncoal.cth.service.InfoMineService;
import cn.itcalvin.sncoal.cth.utils.JwtUtil;
import lombok.val;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class AnalyseServiceImpl implements AnalyseService {

    @Resource
    InfoPfSystemMapper infoPfSystemMapper;
    @Resource
    InfoMineService infoMineService;

    /**
     * 获取当前日期的前6个月的日期（含当月）
     * @return
     */
    private List<String> getPreSixMonth(){
        List<String> monthList=new ArrayList<>();
        Date date= DateUtil.date();
        for (int i = 5; i >= 0; i--) {
            monthList.add(DateUtil.format(DateUtil.offsetMonth(date, -i), "yyyy-MM"));
        }
        return monthList;
    }

    private List<RespSelect> getAllMineListBySelect(RespUserInfo userInfo){
        //根据角色判断取几个矿的数据
        List<RespSelect> mineList = new ArrayList<>();
        if(userInfo.getRoleType()==3){
            final val allMineList = infoMineService.getAllMineList(null);
            mineList = allMineList.getData().stream().map(v -> {
                return new RespSelect(v.getId(), v.getMineName());
            }).collect(Collectors.toList());
        }else if(userInfo.getRoleType()==4){
            mineList.add(new RespSelect(userInfo.getBelongId(),userInfo.getBelongName()));
        }
        return mineList;
    }


    /**
     * 获取某个任务的各个系统评分列表查询
     *
     * @param reqId
     * @return
     */
    @Override
    public RespAnalyse oneMineAllSystem(ReqLong reqId) {
        List<RespOneMineAllSystem> list = infoPfSystemMapper.oneMineAllSystem(reqId.getId());
        RespAnalyse respAnalyse = new RespAnalyse();
        List<String> systemNameList = ConfigCacheUtils.getInstance().getAllSystemList().stream().map(item -> item.getSystemName()).collect(Collectors.toList());
        respAnalyse.setXAxis(systemNameList);
        List<String> monthList = getPreSixMonth();
        respAnalyse.setYNameList(monthList);
        List<List<BigDecimal>> yAxis=new ArrayList<>();
        monthList.forEach(x->{
            List<BigDecimal> tmpList=new ArrayList<>();
            systemNameList.forEach(v->{
                final Optional<RespOneMineAllSystem> first = list.stream().filter(z -> z.getCheckMonth().equals(x) && z.getSystemName().equals(v)).findFirst();
                if (first.isPresent()&&first.get().getZbScore()!=null) {
                    tmpList.add(first.get().getZbScore());
                } else {
                    tmpList.add(new BigDecimal(0));
                }
            });
            yAxis.add(tmpList);
        });
        respAnalyse.setYAxis(yAxis);
        respAnalyse.setTotalYAxis(ConfigCacheUtils.getInstance().getAllSystemList().stream().map(item -> item.getTotalScore()).collect(Collectors.toList()));
        return respAnalyse;
    }

    /**
     * 获取是否存在需要处理的评分
     *
     * @return
     */
    @Override
    public Integer getNotice() {
        final RespUserInfo userInfo = JwtUtil.getUserInfo();
        if(userInfo.getRoleType()==3){
            return infoPfSystemMapper.getHandle();
        }else if(userInfo.getRoleType()==4){
            return infoPfSystemMapper.getHandleByMineId(userInfo.getBelongId());
        }else{
            return 0;
        }
    }

    /**
     * 矿井最后一次所有系统的得分
     * 最后一次两矿各系统的柱状图（X坐标是系统，Y坐标是得分）
     * 矿井查询自己的，矿业公司查询所属矿井的
     *
     * @return
     */
    @Override
    public RespAnalyse mineAllSystemLast() {
        RespAnalyse respAnalyse = new RespAnalyse();
        List<String> systemNameList = ConfigCacheUtils.getInstance().getAllSystemList().stream().map(item -> item.getSystemName()).collect(Collectors.toList());
        respAnalyse.setXAxis(systemNameList);

        //先获取最后一次评分的时间11
       List<RespMineAllSystemLast> list =  infoPfSystemMapper.mineAllSystemLast();
        final val mineList = getAllMineListBySelect(JwtUtil.getUserInfo());
        respAnalyse.setYNameList(mineList.stream().map(v->v.getName()).collect(Collectors.toList()));

        //赋值数据
        List<List<BigDecimal>> listResult=new ArrayList<>();
        mineList.forEach(x->{
            List<BigDecimal> tmpList=new ArrayList<>();
            systemNameList.forEach(v->{
                final Optional<RespMineAllSystemLast> first = list.stream().filter(z -> z.getMineId().equals(x.getId()) && z.getSystemName().equals(v)).findFirst();
                if (first.isPresent()&&first.get().getHyScore()!=null) {
                    tmpList.add(first.get().getHyScore());
                } else {
                    tmpList.add(new BigDecimal(0));
                }
            });
            listResult.add(tmpList);
        });
        respAnalyse.setYAxis(listResult);
        respAnalyse.setTotalYAxis(ConfigCacheUtils.getInstance().getAllSystemList().stream().map(item -> item.getTotalScore()).collect(Collectors.toList()));
        return respAnalyse;
    }

    /**
     * 多个矿井某系统的得分趋势图 （按月，如果一个月有多次，取分数最高的一次）（需查询条件-选择某系统，时间范围是近一年，X坐标是日期，Y坐标是得分）
     * （X坐标是日期，Y坐标是得分）
     * 矿井查询自己的，矿业公司查询所属矿井的
     *
     * @param reqId 系统ID
     * @return
     */
    @Override
    public RespAnalyse mineOneSystem(ReqLong reqId) {
        List<RespMineOneSystem> list =  infoPfSystemMapper.mineOneSystem(reqId.getId());
        RespAnalyse respAnalyse = new RespAnalyse();
        List<String> monthList = getPreSixMonth();
        respAnalyse.setXAxis(monthList);

        //根据角色判断取几个矿的数据
        final val mineList = getAllMineListBySelect(JwtUtil.getUserInfo());
        respAnalyse.setYNameList(mineList.stream().map(v->v.getName()).collect(Collectors.toList()));
        List<List<BigDecimal>> listResult=new ArrayList<>();
        mineList.forEach(x->{
            List<BigDecimal> tmpList=new ArrayList<>();
            monthList.forEach(v->{
                final Optional<RespMineOneSystem> first = list.stream().filter(z -> z.getMineId().equals(x.getId()) && z.getCheckMonth().equals(v)).findFirst();
                if (first.isPresent()&&first.get().getZbScore()!=null) {
                    tmpList.add(first.get().getZbScore());
                } else {
                    tmpList.add(new BigDecimal(0));
                }
            });
            listResult.add(tmpList);
        });
        respAnalyse.setYAxis(listResult);
        final val systemById = ConfigCacheUtils.getInstance().getSystemById(reqId.getId());
        if(systemById!=null){
            systemById.getTotalScore();
            respAnalyse.setTotalYAxis(Arrays.asList(systemById.getTotalScore(),systemById.getTotalScore(),systemById.getTotalScore(),
                    systemById.getTotalScore(),systemById.getTotalScore(),systemById.getTotalScore()));
        }
        return respAnalyse;
    }

    /**
     * 多个矿井总分分趋势图
     *
     * @return
     */
    @Override
    public RespAnalyse mineDateScore() {
        List<RespMineDateScore> list =  infoPfSystemMapper.mineDateScore();
        RespAnalyse respAnalyse = new RespAnalyse();
        List<String> monthList = getPreSixMonth();
        respAnalyse.setXAxis(monthList);
        //根据角色判断取几个矿的数据
        final val mineList = getAllMineListBySelect(JwtUtil.getUserInfo());
        respAnalyse.setYNameList(mineList.stream().map(v->v.getName()).collect(Collectors.toList()));
        List<List<BigDecimal>> listResult=new ArrayList<>();
        mineList.forEach(x->{
            List<BigDecimal> tmpList=new ArrayList<>();
            monthList.forEach(v->{
                final Optional<RespMineDateScore> first = list.stream().filter(z -> z.getMineId().equals(x.getId()) && z.getCheckMonth().equals(v)).findFirst();
                if (first.isPresent()&&first.get().getZbScore()!=null) {
                    tmpList.add(first.get().getZbScore());
                } else {
                    tmpList.add(new BigDecimal(0));
                }
            });
            listResult.add(tmpList);
        });
        respAnalyse.setYAxis(listResult);
        final val bigDecimal = new BigDecimal(100);
        respAnalyse.setTotalYAxis(Arrays.asList( bigDecimal,bigDecimal,bigDecimal,bigDecimal,bigDecimal,bigDecimal));
        return respAnalyse;
    }

    /**
     * 最后一次评测的总分
     *
     * @return
     */
    @Override
    public RespAnalyseCard getStatData() {
        RespAnalyseCard respAnalyseCard = new RespAnalyseCard();
        respAnalyseCard.setCardName("总分");
        respAnalyseCard.setCardId(0L);
        respAnalyseCard.setTotalScore(new BigDecimal(100));
        List<RespAnalyseCardItem> list= infoPfSystemMapper.getStatData();

        List<RespAnalyseCardItem> listTemp=new ArrayList<>();

        final val mineList = getAllMineListBySelect(JwtUtil.getUserInfo());
        mineList.forEach(x->{
            RespAnalyseCardItem respAnalyseCardItem = new RespAnalyseCardItem();
            respAnalyseCardItem.setMineId(x.getId());
            respAnalyseCardItem.setMineName(x.getName());
            final val first = list.stream().filter(v -> v.getMineId().equals(x.getId())).findFirst();
            if (first.isPresent()) {
                respAnalyseCardItem.setPfId(first.get().getPfId());
                respAnalyseCardItem.setSjScore(first.get().getSjScore());
                respAnalyseCardItem.setTotalScore(first.get().getTotalScore());
            }
            listTemp.add(respAnalyseCardItem);
        });
        respAnalyseCard.setAnalyzeCardItems(listTemp);
        return respAnalyseCard;
    }

    /**
     * 两矿最后一次指标得分情况
     *
     * @return
     */
    @Override
    public Map<String, List<RespAnalyseCard>> getStatDataCard() {
        Map<String, List<RespAnalyseCard>> map=new LinkedHashMap<>();
        final val mineList = getAllMineListBySelect(JwtUtil.getUserInfo());
        List<RespStatDataCardTemp> list= infoPfSystemMapper.getStatDataCard();
        final List<ConfigSystem> listSystem = ConfigCacheUtils.getInstance().getAllSystemList();
        listSystem.forEach(x->{
            List<RespAnalyseCard> listTemp=new ArrayList<>();
            map.put(x.getSystemName(),listTemp);
            final RespUserInfo userInfo = JwtUtil.getUserInfo();
            List<ConfigSystemZb> bySystemId;
            List<ConfigSystemZb> allList= ConfigCacheUtils.getInstance().getBySystemId(x.getId());
            if(userInfo.getRoleType().equals(4)){
                bySystemId = allList.stream().filter(xx->
                        (userInfo.getBelongId().equals(xx.getMineId())||xx.getMineId()==null)).collect(Collectors.toList());
            }else{
                bySystemId=allList;
            }

            bySystemId.forEach(y->{
                RespAnalyseCard respAnalyseCard = new RespAnalyseCard();
                listTemp.add(respAnalyseCard);
                respAnalyseCard.setCardId(y.getId());
                respAnalyseCard.setCardName(y.getContent());
                respAnalyseCard.setTotalScore(y.getZbTotalScore());
                List<RespAnalyseCardItem> listCardItem=new ArrayList<>();
                respAnalyseCard.setAnalyzeCardItems(listCardItem);
                mineList.forEach(z->{
                    RespAnalyseCardItem respAnalyseCardItem = new RespAnalyseCardItem();
                    listCardItem.add(respAnalyseCardItem);
                    respAnalyseCardItem.setMineId(z.getId());
                    respAnalyseCardItem.setMineName(z.getName());
                    respAnalyseCardItem.setTotalScore(y.getZbTotalScore());
                    final Optional<RespStatDataCardTemp> first = list.stream().filter(c -> c.getMineId().equals(z.getId()) && c.getSystemZbId().equals(y.getId())).findFirst();
                    if (first.isPresent()) {
                        respAnalyseCardItem.setPfId(first.get().getPfId());
                        respAnalyseCardItem.setSjScore(first.get().getZbSjScore());
                    }else{
                        respAnalyseCardItem.setSjScore(new BigDecimal(0));

                    }

                });

            });
        });
        return map;
    }

    /**
     * 某指标得分明细
     *
     * @param reqAnalyseGetZbDetails
     * @return
     */
    @Override
    public List<RespAnalyseCardDetails> getCardDetails(ReqAnalyseGetZbDetails reqAnalyseGetZbDetails) {
        List<Long> pfIdList=Arrays.stream(reqAnalyseGetZbDetails.getPfIdList().split(",")).map(Long::parseLong).collect(Collectors.toList());
        if(pfIdList.size()<=0){
            return null;
        }

        List<RespAnalyseCardDetailsItem> list= infoPfSystemMapper.getCardDetails(pfIdList,reqAnalyseGetZbDetails.getZbId());
        if(list == null || list.size()<=0){
            return null;
        }
        List<RespAnalyseCardDetails> listResult=new ArrayList<>();
        final val mineList = getAllMineListBySelect(JwtUtil.getUserInfo());

        final Map<Long, List<RespAnalyseCardDetailsItem>> zbDetailsMap = list.stream().collect(Collectors.groupingBy(RespAnalyseCardDetailsItem::getZbDetailsId));

        zbDetailsMap.forEach((key, value) ->{
            RespAnalyseCardDetails respAnalyseCardDetails = new RespAnalyseCardDetails();
            respAnalyseCardDetails.setZbId(key);
            respAnalyseCardDetails.setZbName(value.get(0).getZbDetailsName());
            List<RespAnalyseCardDetailsItem> listTemp=new ArrayList<>();
            respAnalyseCardDetails.setZbDetailsItems(listTemp);
            mineList.forEach(x->{
                RespAnalyseCardDetailsItem respAnalyseCardDetailsItem = new RespAnalyseCardDetailsItem();
                listTemp.add(respAnalyseCardDetailsItem);
                respAnalyseCardDetailsItem.setMineId(x.getId());
                respAnalyseCardDetailsItem.setMineName(x.getName());
                final val first =
                        value.stream().filter(v -> v.getMineId().equals(x.getId())).findFirst();
                if (first.isPresent()) {
                    respAnalyseCardDetailsItem.setZbId(first.get().getZbId());
                    respAnalyseCardDetailsItem.setZbName(first.get().getZbName());
                    respAnalyseCardDetailsItem.setZbDetailsId(first.get().getZbDetailsId());
                    respAnalyseCardDetailsItem.setZbDetailsName(first.get().getZbDetailsName());
                    respAnalyseCardDetailsItem.setZbDetailsContent(first.get().getZbDetailsContent());
                    respAnalyseCardDetailsItem.setZbDetailsType(first.get().getZbDetailsType());
                    respAnalyseCardDetailsItem.setZbDetailsUnit(first.get().getZbDetailsUnit());
                }else{
                    respAnalyseCardDetailsItem.setZbDetailsContent(null);
                }
            });
            listResult.add(respAnalyseCardDetails);
        });
        return listResult;
    }

    /**
     * 某指标明细趋势
     *
     * @param reqId
     * @return
     */
    @Override
    public RespAnalyse oneZbDetails(ReqLong reqId) {
        List<RespMineDateScore> list =  infoPfSystemMapper.oneZbDetails(reqId.getId());
        RespAnalyse respAnalyse = new RespAnalyse();
        List<String> monthList = getPreSixMonth();
        respAnalyse.setXAxis(monthList);
        //根据角色判断取几个矿的数据
        final val mineList = getAllMineListBySelect(JwtUtil.getUserInfo());
        respAnalyse.setYNameList(mineList.stream().map(v->v.getName()).collect(Collectors.toList()));
        List<List<BigDecimal>> listResult=new ArrayList<>();
        mineList.forEach(x->{
            List<BigDecimal> tmpList=new ArrayList<>();
            monthList.forEach(v->{
                final Optional<RespMineDateScore> first = list.stream().filter(z -> z.getMineId().equals(x.getId()) && z.getCheckMonth().equals(v)).findFirst();
                if (first.isPresent()&&first.get().getZbScore()!=null) {
                    tmpList.add(first.get().getZbScore());
                } else {
                    tmpList.add(new BigDecimal(0));
                }
            });
            listResult.add(tmpList);
        });
        respAnalyse.setYAxis(listResult);
        return respAnalyse;
    }
}
